home *** CD-ROM | disk | FTP | other *** search
- Frequently Asked Questions (FAQS);faqs.554
-
-
-
- Certain window managers, notably dxwm and olwm, are very picky about having
- this done.
-
- If you are using Sun's OpenWindows olwm, you can also add this resource
- to your defaults file to use clients that aren't ICCCM-compliant.
- OpenWindows.FocusLenience: true
-
- [mostly courtesy Dave Lemke of NCD and Stuart Marks of Sun]
-
- ----------------------------------------------------------------------
- Subject: 111) How do I figure out what window manager is running?
-
- You can't reliably tell; whatever mechanism you could use could be
- spoofed in any case.
- For most cases, you shouldn't care which window manager is running, so
- long as you do things in an ICCCM-conformant manner. There are some cases in
- which particular window managers are known to do things wrong; checking for
- particular hints placed on the window by the window manager so that you can
- sidestep the problem may be appropriate in these cases. Alternatively, it may
- be appropriate to determine which window manager is running in order to take
- advantage of specific *added* features (such as olwm's push-pin menus) in order
- to give your program *added* functionality. Beware of usurping the window
- manager's functions by providing that functionality even when it is missing;
- this surely leads to future compatibility problems.
-
- ----------------------------------------------------------------------
- Subject: 112) Is there a skeleton X program available?
-
- There is no general framework such as the TransSkel program for the
- Macintosh which handles lots of the odds and ends and overhead of development
- under a window system and which can be used as a platform for additional
- development. In X, the problem is typically solved by using an interactive
- application builder tool or by using cut&paste on existing X applications. Good
- applications which you might look to manipulate when you want to "test just
- this one little thing" include contrib/clients/xskel, a simple R4 program that
- puts up a window and allows sketching in it and offers a starting point for
- quick hacks, the Xaw examples in the examples/ directory in the R3 and R4
- distributions, and the Xlib "Hello World" example in the R3 doc/HelloWorld and
- R4 doc/tutorials/HelloWorld; an updated version of this program which uses R4
- Xlib calls and current ICCCM conventions was posted in 2/90 to comp.windows.x
- by Glenn Widener of Tektronix. [3/90]
-
- In addition, a sample Xt program (for Xaw or Xm) by Rainer Klute
- showing how to open multiple displays and how to catch a broken display
- connection is available on export.lcs.mit.edu in contrib/mdisp.tar.Z. [4/92]
-
- ----------------------------------------------------------------------
- Subject: 113) Why does XtGetValues not work for me (sic)?
-
- The XtGetValues interface for retrieving resources from a widget is
- sensitive to the type of variable. Your code may be doing something like this:
- {
- Arg args[3];
- int i;
- int sensitive; /* oops; wrong data type */
- i=0;
- XtSetArg (args[i], XtNsensitive, &sensitive); i++;
- XtGetValues(widget, args, i );
- ...
- }
-
- But XtNsensitive is a Boolean, which on most machines is a single byte;
- declaring the variable "sensitive" as Boolean works properly. This problem
- comes up often when using particular toolkits that redefine the Xt types
- Dimension and Position; code that assumes they are int will have similar
- problems if those types are actually short. In general: you are safe if you
- use the actual type of the resource, as it appears in the widget's man page.
- [11/90]
-
- ----------------------------------------------------------------------
- Subject: 114) Why don't XtConfigureWidget/XtResizeWidget/XtMoveWidget work?
-
- You're probably trying to use these functions from application code.
- They should be used only internally to widgets; these functions are for a
- parent widget to change the geometry of its children. Other promising
- functions, XtMakeGeometryRequest() and XtMakeResizeRequest(), are also for use
- only by widgets, in this case by a child to request a change from its parent.
- The only way for your application to request a geometry change for a
- widget is to issue an XtSetValues call setting some of the geometry resources.
- Although this will result in the widget-internal functions' being called, your
- application code must use the standard XtSetValues interface or risk the
- widgets' data becoming corrupted.
- [The Xlib calls XMoveWindow() and XResizeWindow() should similarly be
- avoided; they shouldn't be used to change XtNx, XtNy, XtNwidth, or XtNheight.]
-
- ----------------------------------------------------------------------
- Subject: 115) Why isn't there an XtReparentWidget call like XReparentWindow?
-
- Although there are various details of the current implementation of
- the Xt internals which make reparenting difficult, the major reason that no
- such call exists is that it remains undefined what the set of resources for
- the "new" widget should be. Resources are typically set based on the location
- in the instance hierarchy; what resources should change if the instance moves?
- What should happen to the widget's children? And by the time such semantics are
- defined, there would probably be little advantage over destroying the old
- widget and creating a new widget in the correct location with the desired
- resources, as setting the resources correctly is the majority of work in
- creating a new widget.
-
- Note that reparenting is possible in the OI toolkit.
-
- ----------------------------------------------------------------------
- Subject: 116) I'm writing a widget and can't use a float as a resource value.
-
- Float resources are not portable; the size of the value may be larger than
- the size of an XtPointer. Try using a pointer to a float instead; the Xaw
- Scrollbar float resources are handled in this way.
-
- ----------------------------------------------------------------------
- Subject: 117) Is this a memory leak in the X11R4 XtDestroyWidget()?!
-
- Yes. This is the "unofficial" fix-19 for the X11R4 Destroy.c:
-
- *** Destroy.c.1.37 Thu Jul 11 15:41:25 1991
- --- lib/Xt/Destroy.c Thu Jul 11 15:42:23 1991
- ***************
- *** 1,4 ****
- --- 1,5 ----
- /* $XConsortium: Destroy.c,v 1.37 90/09/28 10:21:32 swick Exp $ */
- + /* Plus unofficial patches in revisions 1.40 and 1.41 */
-
- /***********************************************************
- Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
- ***************
- *** 221,239 ****
- */
-
- int i = 0;
- ! DestroyRec* dr = app->destroy_list;
- while (i < app->destroy_count) {
- if (dr->dispatch_level >= dispatch_level) {
- Widget w = dr->widget;
- if (--app->destroy_count)
- bcopy( (char*)(dr+1), (char*)dr,
- ! app->destroy_count*sizeof(DestroyRec)
- );
- XtPhase2Destroy(w);
- }
- else {
- i++;
- - dr++;
- }
- }
- }
- --- 222,245 ----
- */
-
- int i = 0;
- ! DestroyRec* dr;
- while (i < app->destroy_count) {
- +
- + /* XtPhase2Destroy can result in calls to XtDestroyWidget,
- + * and these could cause app->destroy_list to be reallocated.
- + */
- +
- + dr = app->destroy_list + i;
- if (dr->dispatch_level >= dispatch_level) {
- Widget w = dr->widget;
- if (--app->destroy_count)
- bcopy( (char*)(dr+1), (char*)dr,
- ! (app->destroy_count - i) * sizeof(DestroyRec)
- );
- XtPhase2Destroy(w);
- }
- else {
- i++;
- }
- }
- }
-
- [from Donna Converse, converse@expo.lcs.mit.EDU]
-
- ----------------------------------------------------------------------
- Subject: 118) Are callbacks guaranteed to be called in the order registered?
-
- Although some books demonstrate that the current implementation of Xt
- happens to call callback procedures in the order in which they are registered,
- the specification does not guarantee such a sequence, and supplemental
- authoritative documents (i.e. the Asente/Swick volume) do say that the order is
- undefined. Because the callback list can be manipulated by both the widget and
- the application, Xt cannot guarantee the order of execution.
- In general, the callback procedures should be thought of as operating
- independently of one another and should not depend on side-effects of other
- callbacks operating; if a seqence is needed, then the single callback to be
- registered can explicitly call other functions necessary.
-
- [4/92; thanks to converse@expo.lcs.mit.edu]
-
- ----------------------------------------------------------------------
- Subject: 119) Why doesn't XtDestroyWidget() actually destroy the widget?
-
- XtDestroyWidget() operates in two passes, in order to avoid leaving
- dangling data structures; the function-call marks the widget, which is not
- actually destroyed until your program returns to its event-loop.
-
- ----------------------------------------------------------------------
- Subject: 120) How do I query the user synchronously using Xt?
-
- It is possible to have code which looks like this trivial callback,
- which has a clear flow of control. The calls to AskUser() block until answer
- is set to one of the valid values. If it is not a "yes" answer, the code drops
- out of the callback and back to an event-processing loop:
-
- void quit(Widget w, XtPointer client, XtPointer call)
- {
- int answer;
- answer = AskUser(w, "Really Quit?");
- if (RET_YES == answer)
- {
- answer = AskUser(w, "Are You Really Positive?");
- if (RET_YES == answer)
- exit(0);
- }
- }
-
- A more realistic example might ask whether to create a file or whether
- to overwrite it.
- This is accomplished by entering a second event-processing loop and
- waiting until the user answers the question; the answer is returned to the
- calling function. That function AskUser() looks something like this, where the
- Motif can be replaced with widget-set-specific code to create some sort of
- dialog-box displaying the question string and buttons for "OK", "Cancel" and
- "Help" or equivalents:
-
- int AskUser(w, string)
- Widget w;
- char *string;
- {
- int answer=RET_NONE; /* some not-used marker */
- Widget dialog; /* could cache&carry, but ...*/
- Arg args[3];
- int n = 0;
- XtAppContext context;
-
- n=0;
- XtSetArg(args[n], XmNmessageString, XmStringCreateLtoR(string,
- XmSTRING_DEFAULT_CHARSET)); n++;
- XtSetArg(args[n], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL); n++;
- dialog = XmCreateQuestionDialog(XtParent(w), string, args, n);
- XtAddCallback(dialog, XmNokCallback, response, &answer);
- XtAddCallback(dialog, XmNcancelCallback, response, &answer);
- XtAddCallback(dialog, XmNhelpCallback, response, &answer);
- XtManageChild(dialog);
-
- context = XtWidgetToApplicationContext (w);
- while (answer == RET_NONE || XtAppPending(context)) {
- XtAppProcessEvent (context, XtIMAll);
- }
- XtDestroyWidget(dialog); /* blow away the dialog box and shell */
- return answer;
- }
-
- The dialog supports three buttons, which are set to call the same
- function when tickled by the user. The variable answer is set when the user
- finally selects one of those choices:
-
- void response(w, client, call)
- Widget w;
- XtPointer client;
- XtPointer call;
- {
- int *answer = (int *) client;
- XmAnyCallbackStruct *reason = (XmAnyCallbackStruct *) call;
- switch (reason->reason) {
- case XmCR_OK:
- *answer = RET_YES; /* some #define value */
- break;
- case XmCR_CANCEL:
- *answer = RET_NO;
- break;
- case XmCR_HELP:
- *answer = RET_HELP;
- break;
- default:
- return;
- }
- }
-
- and the code unwraps back to the point at which an answer was needed and
- continues from there.
-
- [Thanks to Dan Heller (argv@sun.com); further code is in Dan's R3/contrib
- WidgetWrap library. 2/91]
-
- ----------------------------------------------------------------------
- Subject: 121) How do I determine the name of an existing widget?
- I have a widget ID and need to know what the name of that widget is.
-
- Users of R4 and later are best off using the XtName() function, which
- will work on both widgets and non-widget objects.
-
- If you are still using R3, you can use this simple bit of code to do
- what you want. Note that it depends on the widget's internal data structures
- and is not necessarily portable to future versions of Xt, including R4.
-
- #include <X11/CoreP.h>
- #include <X11/Xresource.h>
- String XtName (widget)
- Widget widget; /* WILL work with non-widget objects */
- {
- return XrmNameToString(widget->core.xrm_name);
- }
-
- [7/90; modified with suggestion by Larry Rogers (larry@boris.webo.dg.com) 9/91]
-
- ----------------------------------------------------------------------
- Subject: 122) What widget is appropriate to use as a drawing canvas?
-
- Some widget sets have a widget particularly for this purpose -- a
- WorkSpace or DrawingArea which doesn't display anything but lets your Xt
- application know when it has been re-exposed, resized, and when it has received
- user key and mouse input.
- The best thing to do for other widget sets -- including the Athena set
- -- is to create or obtain such a widget; this is preferable to drawing into a
- core widget and grabbing events with XtAddEventHandler(), which loses a number
- of benefits of Xt and encapsulation of the functionality . At least one
- version has been posted to comp.sources.x (name???). The publicly-available
- programs xball and xpic include other versions. And the Athena Widget manual
- (mit/doc/Xaw/Template in the R5 distribution) includes a tutorial and source
- code to a simple widget which is suitable for use.
-
- ----------------------------------------------------------------------
- Subject: 123) Why do I get a BadDrawable error drawing to XtWindow(widget)?
- I'm doing this in order to get a window into which I can do Xlib graphics
- within my Xt-based program:
-
- > canvas = XtCreateManagedWidget ( ...,widgetClass,...) /* drawing area */
- > ...
- > window = XtWindow(canvas); /* get the window associated with the widget */
- > ...
- > XDrawLine (...,window,...); /* produces error */
-
- The window associated with the widget is created as a part of the
- realization of the widget. Using a window id of NULL ("no window") could
- create the error that you describe. It is necessary to call XtRealizeWidget()
- before attempting to use the window associated with a widget.
- Note that the window will be created after the XtRealizeWidget() call,
- but that the server may not have actually mapped it yet, so you should also
- wait for an Expose event on the window before drawing into it.
-
- ----------------------------------------------------------------------
- Subject: 124) Why do I get a BadMatch error when calling XGetImage?
-
- The BadMatch error can occur if the specified rectangle goes off the edge of
- the screen. If you don't want to catch the error and deal with it, you can take
- the following steps to avoid the error:
-
- 1) Make a pixmap the same size as the rectangle you want to capture.
- 2) Clear the pixmap to background using XFillRectangle.
- 3) Use XCopyArea to copy the window to the pixmap.
- 4) If you get a NoExpose event, the copy was clean. Use XGetImage to grab the
- image from the pixmap.
- 5) If you get one or more GraphicsExpose events, the copy wasn't clean, and
- the x/y/width/height members of the GraphicsExpose event structures tell you
- the parts of the pixmap which aren't good.
- 6) Get rid of the pixmap; it probably takes a lot of memory.
-
- [10/92; thanks to Oliver Jones (oj@pictel.com)]
-
- ----------------------------------------------------------------------
- Subject: 125) How can my application tell if it is being run under X?
-
- A number of programs offer X modes but otherwise run in a straight
- character-only mode. The easiest way for an application to determine that it is
- running on an X display is to attempt to open a connection to the X server:
-
- display = XOpenDisplay(display_name);
- if (display)
- { do X stuff }
- else
- { do curses or something else }
- where display_name is either the string specified on the command-line following
- -display, by convention, or otherwise is (char*)NULL [in which case
- XOpenDisplay uses the value of $DISPLAY, if set].
-
- This is superior to simply checking for the existence a -display command-line
- argument or checking for $DISPLAY set in the environment, neither of which is
- adequate. [5/91]
-
- ----------------------------------------------------------------------
- Subject: 126)! How do I make a "busy cursor" while my application is computing?
- Is it necessary to call XDefineCursor() for every window in my application?
-
- The easiest thing to do is to create a single InputOnly window that is
- as large as the largest possible screen; make it a child of your toplevel
- window and it will be clipped to that window, so it won't affect any other
- application. (It needs to be as big as the largest possible screen in case the
- user enlarges the window while it is busy or moves elsewhere within a virtual
- desktop.) Substitute "toplevel" with your top-most widget here (similar code
- should work for Xlib-only applications; just use your top Window):
-
- unsigned long valuemask;
- XSetWindowAttributes attributes;
-
- /* Ignore device events while the busy cursor is displayed. */
- valuemask = CWDontPropagate | CWCursor;
- attributes.do_not_propagate_mask = (KeyPressMask | KeyReleaseMask |
- ButtonPressMask | ButtonReleaseMask | PointerMotionMask);
- attributes.cursor = XCreateFontCursor(XtDisplay(toplevel), XC_watch);
-
- /* The window will be as big as the display screen, and clipped by
- its own parent window, so we never have to worry about resizing */
- XCreateWindow(XtDisplay(toplevel), XtWindow(toplevel), 0, 0,
- 65535, 65535, (unsigned int) 0, CopyFromParent, InputOnly,
- CopyFromParent, valuemask, &attributes);
-
- where the maximum size above could be replaced by the real size of the screen,
- particularly to avoid servers which have problems with windows larger than
- 32767.
-
- When you want to use this busy cursor, map and raise this window; to go back to
- normal, unmap it. This will automatically keep you from getting extra mouse
- events; depending on precisely how the window manager works, it may or may not
- have a similar effect on keystrokes as well.
-
- In addition, note also that most of the Xaw widgets support an XtNcursor
- resource which can be temporarily reset, should you merely wish to change the
- cursor without blocking pointer events.
-
- [thanks to Andrew Wason (aw@cellar.bae.bellcore.com), Dan Heller
- (argv@sun.com), and mouse@larry.mcrcim.mcgill.edu; 11/90,5/91]
-
- ----------------------------------------------------------------------
- Subject: 127) How do I fork without hanging my parent X program?
-
- An X-based application which spawns off other Unix processes which
- continue to run after it is closed typically does not vanish until all of its
- children are terminated; the children inherit from the parent the open X
- connection to the display.
- What you need to do is fork; then, immediately, in the child process,
- close (ConnectionNumber(XtDisplay(widget)));
- to close the file-descriptor in the display information. After this do your
- exec. You will then be able to exit the parent.
-
- [Thanks to Janet Anstett (anstettj@tramp.Colorado.EDU) and Gordon Freedman
- (gjf00@duts.ccc.amdahl.com) 2/91]
-
- ----------------------------------------------------------------------
- Subject: 128) Can I make Xt or Xlib calls from a signal handler?
-
- No. Xlib and Xt have no mutual exclusion for protecting critical
- sections. If your signal handler makes such a call at the wrong time (which
- might be while the function you are calling is already executing), it can leave
- the library in an inconsistent state. Note that the ANSI C standard points
- out that behavior of a signal handler is undefined if the signal handler calls
- any function other than signal() itself, so this is not a problem specific to
- Xlib and Xt; the POSIX specification mentions other functions which may be
- called safely but it may not be assumed that these functions are called by
- Xlib or Xt functions.
- You can work around the problem by setting a flag in the interrupt
- handler and later checking it with a work procedure or a timer event which
- has previously been added.
-
- Note: the article in The X Journal 1:4 and the example in O'Reilly
- Volume 6 are in error.
-
- [Thanks to Pete Ware (ware@cis.ohio-state.edu) and Donna Converse
- (converse@expo.lcs.mit.EDU), 5/92]
-
- ----------------------------------------------------------------------
- Subject: 129) What are these "Xlib sequence lost" errors?
-
- You may see these errors if you issue Xlib requests from an Xlib error
- handler, or, more likely, if you make calls which generate X requests to Xt or
- Xlib from a signal handler, which you shouldn't be doing in any case.
-
- ----------------------------------------------------------------------
- Subject: 130) How can my Xt program handle socket, pipe, or file input?
-
- It's very common to need to write an Xt program that can accept input
- both from a user via the X connection and from some other file descriptor, but
- which operates efficiently and without blocking on either the X connection or
- the other file descriptor.
- A solution is use XtAppAddInput(). After you open your file descriptor,
- use XtAppAddInput() to register an input handler. The input handler will be
- called every time there is something on the file descriptor requiring your
- program's attention. Write the input handler like you would any other Xt
- callback, so it does its work quickly and returns. It is important to use only
- non-blocking I/O system calls in your input handlers.
- Most input handlers read the file descriptor, although you can have an
- input handler write or handle exception conditions if you wish.
- Be careful when you register an input handler to read from a disk file.
- You will find that the function is called even when there isn't input pending.
- XtAppAddInput() is actually working as it is supposed to. The input handler is
- called whenever the file descriptor is READY to be read, not only when there is
- new data to be read. A disk file (unlike a pipe or socket) is almost always
- ready to be read, however, if only because you can spin back to the beginning
- and read data you've read before. The result is that your function will almost
- always be called every time around XtAppMainLoop(). There is a way to get the
- type of interaction you are expecting; add this line to the beginning of your
- function to test whether there is new data:
- if (ioctl(fd, FIONREAD, &n) == -1 || n == 0) return;
- But, because this is called frequently, your application is effectively in a
- busy-wait; you may be better off not using XtAppAddInput() and instead setting
- a timer and in the timer procedure checking the file for input.
-
- [courtesy Dan Heller (argv@ora.com), 8/90; mouse@larry.mcrcim.mcgill.edu 5/91;
- Ollie Jones (oj@pictel.com) 6/92]
-
- ----------------------------------------------------------------------
- Subject: 131) How do I simulate a button press/release event for a widget?
-
- You can do this using XSendEvent(); it's likely that you're not setting
- the window field in the event, which Xt needs in order to match to the widget
- which should receive the event.
- If you're sending events to your own application, then you can use
- XtDispatchEvent() instead. This is more efficient than XSendEvent() in that you
- avoid a round-trip to the server.
- Depending on how well the widget was written, you may be able to call
- its action procedures in order to get the effects you want.
-
- [courtesy Mark A. Horstman (mh2620@sarek.sbc.com), 11/90]
-
- ----------------------------------------------------------------------
- Subject: 132) Why doesn't anything appear when I run this simple program?
-
- > ...
- > the_window = XCreateSimpleWindow(the_display,
- > root_window,size_hints.x,size_hints.y,
- > size_hints.width,size_hints.height,BORDER_WIDTH,
- > BlackPixel(the_display,the_screen),
- > WhitePixel(the_display,the_screen));
- > ...
- > XSelectInput(the_display,the_window,ExposureMask|ButtonPressMask|
- > ButtonReleaseMask);
- > XMapWindow(the_display,the_window);
- > ...
- > XDrawLine(the_display,the_window,the_GC,5,5,100,100);
- > ...
-
- You are right to map the window before drawing into it. However, the
- window is not ready to be drawn into until it actually appears on the screen --
- until your application receives an Expose event. Drawing done before that will
- generally not appear. You'll see code like this in many programs; this code
- would appear after window was created and mapped:
- while (!done)
- {
- XNextEvent(the_display,&the_event);
- switch (the_event.type) {
- case Expose: /* On expose events, redraw */
- XDrawLine(the_display,the_window,the_GC,5,5,100,100);
- break;
- ...
- }
- }
-
- Note that there is a second problem: some Xlib implementations don't
- set up the default graphics context to have correct foreground/background
- colors, so this program could previously include this code:
- ...
- the_GC_values.foreground=BlackPixel(the_display,the_screen); /* e.g. */
- the_GC_values.background=WhitePixel(the_display,the_screen); /* e.g. */
- the_GC = XCreateGC(the_display,the_window,
- GCForeground|GCBackground,&the_GC_values);
- ...
-
- Note: the code uses BlackPixel and WhitePixel to avoid assuming that 1 is
- black and 0 is white or vice-versa. The relationship between pixels 0 and 1
- and the colors black and white is implementation-dependent. They may be
- reversed, or they may not even correspond to black and white at all.
-
- Also note that actually using BlackPixel and WhitePixel is usually the wrong
- thing to do in a finished program, as it ignores the user's preference for
- foreground and background.
-
- And also note that you can run into the same situation in an Xt-based program
- if you draw into the XtWindow(w) right after it has been realized; it may
- not yet have appeared.
-
- ----------------------------------------------------------------------
- Subject: 133) What is the difference between a Screen and a screen?
-
- The 'Screen' is an Xlib structure which includes the information about
- one of the monitors or virtual monitors which a single X display supports. A
- server can support several independent screens. They are numbered unix:0.0,
- unix:0.1, unix:0.2, etc; the 'screen' or 'screen_number' is the second digit --
- the 0, 1, 2 which can be thought of as an index into the array of available
- Screens on this particular Display connection.
- The macros which you can use to obtain information about the particular
- Screen on which your application is running typically have two forms -- one
- which takes a Screen and one with takes both the Display and the screen_number.
- In Xt-based programs, you typically use XtScreen(widget) to determine
- the Screen on which your application is running, if it uses a single screen.
- (Part of the confusion may arise from the fact that some of the macros
- which return characteristics of the Screen have "Display" in the names --
- XDisplayWidth, XDisplayHeight, etc.)
-
- ----------------------------------------------------------------------
- Subject: 134) Can I use C++ with X11? Motif? XView?
-
- The X11R4/5 header files are compatible with C++. The Motif 1.1 header
- files are usable as is inside extern "C" {...}. However, the definition of
- String in Intrinsic.h can conflict with the libg++ or other String class and
- needs to be worked around.
-
- Some other projects which can help:
- WWL, a set of C++ classes by Jean-Daniel Fekete to wrap X Toolkit
- widgets, available via anonymous FTP from export.lcs.mit.edu as
- contrib/WWL-1.2.tar.Z [7/92] or lri.lri.fr (129.175.15.1) as pub/WWL-1.2.tar.Z.
- It works by building a set of C++ classes in parallel to the class tree of the
- widgets.
- The C++ InterViews toolkit is obtainable via anonymous FTP from
- interviews.stanford.edu. InterViews uses a box/glue model similar to that of
- TeX for constructing user interfaces and supports multiple looks on the user
- interfaces. Some of its sample applications include a WYSIWIG document editor
- (doc), a MacDraw-like drawing program (idraw) and an interface builder (ibuild).
- THINGS, a class library written at the Rome Air Force Base by the
- Strategic Air Command, available as freeware on archive sites.
-